From 55ee36debfd765ccfa3e2a0621e90ea570663d89 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Tue, 21 Feb 2006 17:13:30 +0000 Subject: [PATCH] tpm: Fixes and cleanup Fix a recently found problem in tpm.c, move the vtpm sysfs entry to /sys/device/platform/tpm_vtpm and add locking in the vtpm hotplug script. Signed-off-by: Stefan Berger --- linux-2.6-xen-sparse/drivers/char/tpm/tpm.c | 13 +++---- linux-2.6-xen-sparse/drivers/char/tpm/tpm.h | 5 +++ .../drivers/char/tpm/tpm_xen.c | 38 ++++++++++++------- .../drivers/xen/tpmback/interface.c | 3 -- .../drivers/xen/tpmback/tpmback.c | 4 -- tools/examples/vtpm | 8 +++- tools/examples/vtpm-common.sh | 9 +++++ 7 files changed, 50 insertions(+), 30 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c index aefbab67e3..9709a60f44 100644 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c @@ -53,7 +53,7 @@ static void timeout_work(void * ptr) down(&chip->buffer_mutex); atomic_set(&chip->data_pending, 0); - memset(chip->data_buffer, 0, chip->vendor->buffersize); + memset(chip->data_buffer, 0, get_chip_buffersize(chip)); up(&chip->buffer_mutex); } @@ -352,7 +352,7 @@ int tpm_open(struct inode *inode, struct file *file) spin_unlock(&driver_lock); - chip->data_buffer = kmalloc(chip->vendor->buffersize * sizeof(u8), GFP_KERNEL); + chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8), GFP_KERNEL); if (chip->data_buffer == NULL) { chip->num_opens--; put_device(chip->dev); @@ -400,8 +400,8 @@ ssize_t tpm_write(struct file *file, const char __user *buf, down(&chip->buffer_mutex); - if (in_size > chip->vendor->buffersize) - in_size = chip->vendor->buffersize; + if (in_size > get_chip_buffersize(chip)) + in_size = get_chip_buffersize(chip); if (copy_from_user (chip->data_buffer, (void __user *) buf, in_size)) { @@ -411,7 +411,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf, /* atomic tpm command send and result receive */ out_size = tpm_transmit(chip, chip->data_buffer, - chip->vendor->buffersize); + get_chip_buffersize(chip)); atomic_set(&chip->data_pending, out_size); atomic_set(&chip->data_position, 0); @@ -432,8 +432,6 @@ ssize_t tpm_read(struct file * file, char __user *buf, int ret_size; int pos, pending = 0; - del_singleshot_timer_sync(&chip->user_read_timer); - flush_scheduled_work(); ret_size = atomic_read(&chip->data_pending); if (ret_size > 0) { /* relay data */ if (size < ret_size) @@ -457,6 +455,7 @@ ssize_t tpm_read(struct file * file, char __user *buf, if ( ret_size <= 0 || pending == 0 ) { atomic_set( &chip->data_pending, 0 ); del_singleshot_timer_sync(&chip->user_read_timer); + flush_scheduled_work(); } return ret_size; diff --git a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h index 8908179c66..090b889638 100644 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h @@ -101,6 +101,11 @@ static inline void tpm_write_index(int base, int index, int value) outb(value & 0xFF, base+1); } +static inline u32 get_chip_buffersize(struct tpm_chip *chip) +{ + return chip->vendor->buffersize; +} + extern int tpm_register_hardware(struct device *, struct tpm_vendor_specific *); extern int tpm_open(struct inode *, struct file *); diff --git a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c index c3c571c3ff..0ee6920439 100644 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "tpm.h" /* read status bits */ @@ -455,9 +456,7 @@ static struct tpm_vendor_specific tpm_xen = { .buffersize = 64 * 1024, }; -static struct device tpm_device = { - .bus_id = "vtpm", -}; +static struct platform_device *pdev; static struct tpmfe_device tpmfe = { .receive = tpm_recv, @@ -477,23 +476,22 @@ static int __init init_xen(void) * driver */ if ((rc = tpm_fe_register_receiver(&tpmfe)) < 0) { - return rc; + goto err_exit; } /* * Register our device with the system. */ - if ((rc = device_register(&tpm_device)) < 0) { - tpm_fe_unregister_receiver(); - return rc; + pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0); + if (IS_ERR(pdev)) { + rc = PTR_ERR(pdev); + goto err_unreg_fe; } tpm_xen.buffersize = tpmfe.max_tx_size; - if ((rc = tpm_register_hardware(&tpm_device, &tpm_xen)) < 0) { - device_unregister(&tpm_device); - tpm_fe_unregister_receiver(); - return rc; + if ((rc = tpm_register_hardware(&pdev->dev, &tpm_xen)) < 0) { + goto err_unreg_pdev; } dataex.current_request = NULL; @@ -508,13 +506,25 @@ static int __init init_xen(void) disconnect_time = jiffies; return 0; + + +err_unreg_pdev: + platform_device_unregister(pdev); +err_unreg_fe: + tpm_fe_unregister_receiver(); + +err_exit: + return rc; } static void __exit cleanup_xen(void) { - tpm_remove_hardware(&tpm_device); - device_unregister(&tpm_device); - tpm_fe_unregister_receiver(); + struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); + if (chip) { + tpm_remove_hardware(chip->dev); + platform_device_unregister(pdev); + tpm_fe_unregister_receiver(); + } } module_init(init_xen); diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c index 138dd9854f..eebe9c84aa 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c @@ -14,9 +14,6 @@ #include "common.h" #include -#define TPMIF_HASHSZ (2 << 5) -#define TPMIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(TPMIF_HASHSZ-1)) - static kmem_cache_t *tpmif_cachep; int num_frontends = 0; diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c index 573c03da9d..7b9570440e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c @@ -66,8 +66,6 @@ static int packet_read_shmem(struct packet *pak, u32 left); -#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE - #define MIN(x,y) (x) < (y) ? (x) : (y) @@ -973,8 +971,6 @@ static void processing_timeout(unsigned long ptr) static void tpm_tx_action(unsigned long unused); static DECLARE_TASKLET(tpm_tx_tasklet, tpm_tx_action, 0); -#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE - static struct list_head tpm_schedule_list; static spinlock_t tpm_schedule_list_lock; diff --git a/tools/examples/vtpm b/tools/examples/vtpm index 2d590a0158..553c8a0904 100644 --- a/tools/examples/vtpm +++ b/tools/examples/vtpm @@ -3,6 +3,7 @@ dir=$(dirname "$0") . "$dir/vtpm-common.sh" +vtpm_fatal_error=0 case "$command" in add) @@ -19,5 +20,8 @@ case "$command" in ;; esac -log debug "Successful vTPM operation '$command'." -success +if [ $vtpm_fatal_error -eq 0 ]; then + log debug "Successful vTPM operation '$command'." + success +fi + diff --git a/tools/examples/vtpm-common.sh b/tools/examples/vtpm-common.sh index 8344fdcfef..72c16abd9e 100644 --- a/tools/examples/vtpm-common.sh +++ b/tools/examples/vtpm-common.sh @@ -173,6 +173,7 @@ function validate_entry () { local vmname=$1 local inst=$2 local res + res=`cat $VTPMDB | \ gawk -vvmname=$vmname \ -vinst=$inst \ @@ -238,6 +239,9 @@ function vtpm_create_instance () { local res set +e get_create_reason + + claim_lock vtpmdb + find_instance $domname res=$? if [ $res -eq 0 ]; then @@ -262,6 +266,9 @@ function vtpm_create_instance () { vtpm_create $instance fi fi + + release_lock vtpmdb + if [ "$REASON" == "create" ]; then vtpm_reset $instance elif [ "$REASON" == "resume" ]; then @@ -292,3 +299,5 @@ function vtpm_remove_instance () { fi set -e } + + -- 2.30.2